// 引入 MongoDB 中间件
const mongoose = Require('mongoose');
// 初始化 MongoDB 格式化程序
const Schema = mongoose.Schema;

// 文件 module
const contentSchema = new Schema({
    title: { type: String, required: true },
    requestURL: { type: String },
    header: { type: String },
    requestData: { type: String },
    contentType: { type: String, enum: ['POST', 'GET', 'PUT', 'DEL', 'folder'], required: true },
    contentIndex: { type: Number, min: 1, default: 1 },
    parentId: { type: String, default: null },
    description: String,
    disable: { type: Boolean, default: false },
    code: { type: String },
    formData: { type: String },
    requestType: { type: String, enum: ['json', 'form'] },
}, { timestamps: true });

// 格式化单行数据
// 为了保证前端返回值一致性

var formatDoc = function (doc) {
    var data = doc.toJSON({ getters: true });
    data.id = doc._id.toString();
    // data.createdAt = doc.createdAt.getTime();
    // data.updatedAt = doc.updatedAt.getTime();

    if (!data.hasOwnProperty('code')) {
        data.code = '';
    };
    if (!data.hasOwnProperty('formData')) {
        data.formData = '';
    };
    if (!data.hasOwnProperty('requestType')) {
        data.requestType = 'json';
    };
    delete data.createdAt;
    delete data.updatedAt;
    delete data.disable;
    delete data._id;
    return data;
};
// 格式化多行数据
var formatDocs = function (docs) {
    var _array = [];
    for (let i = 0; i < docs.length; i++) {
        const item = formatDoc(docs[i]);
        _array.push(item);
    };
    return _array;
};

// 创建数据库代理方法
var DataBase = function (options) {
    this.options = options;
    // 基本设置
    var username = this.options.username;
    var password = this.options.password;
    var ip = this.options.ip;
    var port = this.options.port;
    var DBName = this.options.DBName;
    // var DBURL = this.options.DBURL; 
    var PorjectName = 'API';

    this.module = null;
    // 错误信息 (链接未完成时)
    this.DBMessage = { message: 'HODE ON' };
    var _this = this;

    var DBURL = 'mongodb://';

    // MongoDB 数据库可不输入用户名及密码
    if (username && password) {
        DBURL = DBURL + username + ':' + password + '@';
    };

    // 创建完整数据库链接
    DBURL = DBURL + ip + ':' + (port ? port : '80') + '/' + DBName;
    var _this = this;

    // 链接数据库
    mongoose.connect(DBURL, { config: { autoIndex: false } });

    this.openEvent = function () { };

    // 当数据库发生错误时
    mongoose.connection.on("error", (error) => {
        alert(error.message);
        this.openEvent('数据库连接错误');
        this.DBMessage = error.message;
    });

    // 当数据库成功链接是
    mongoose.connection.on("open", () => {
        this.openEvent();
        this.DBMessage.message = false;
        this.module = mongoose.model(PorjectName, contentSchema, PorjectName);
        // _this.PorjectModule = mongoose.model(PorjectTitle, PorjectSchema, PorjectTitle);
    });
};
DataBase.prototype.onOpen = function (event) {
    this.openEvent = event;
};
DataBase.prototype.creat = function (doc, cb) {
    // 创建一条记录
    // 当DBMessage有值时，返回错误信息
    if (this.DBMessage.message) {
        cb(this.DBMessage.message.message, null);
    } else {
        var data = new this.module(doc);
        // 将单行数据插入到数据库
        data.save(function (err, doc) {
            if (err) {
                cb(err.message, null);
            } else {
                cb(false, formatDoc(doc));
            };
        });
    };
};
DataBase.prototype.getAll = function (cb) {
    // 查找全部数据
    // 查找条件为数据库的disable字段为false(代表正常使用)
    if (this.DBMessage.message) {
        cb(this.DBMessage.message, null);
    } else {
        this.module.find({ disable: false }, function (err, docs) {
            if (err) {
                cb(err.message, null);
            } else {
                cb(false, formatDocs(docs));
            };
        });
    };
};
DataBase.prototype.upData = function (id, _doc, cb) {
    if (this.DBMessage.message) {
        cb(this.DBMessage.message, null);
    } else {
        // 更新数据库单条记录
        this.module.findById(id, function (err, doc) {
            doc.title = _doc.title;
            doc.requestURL = _doc.requestURL;
            doc.requestData = _doc.requestData;
            doc.contentType = _doc.contentType;
            doc.header = _doc.header;
            doc.contentIndex = _doc.contentIndex;
            doc.parentId = _doc.parentId;
            doc.description = _doc.description;
            doc.disable = false;
            doc.code = _doc.code;
            doc.formData = _doc.formData;
            doc.requestType = _doc.requestType;
            // 储存数据
            doc.save(function (err, doc) {
                if (err) {
                    cb(err.message, null);
                } else {
                    cb(false, formatDoc(doc));
                };
            })
        });
    };
};
DataBase.prototype.delete = function (id, cb) {
    if (this.DBMessage.message) {
        cb(this.DBMessage.message, null);
    } else {
        // 删除单条记录
        this.module.findById(id, (err, doc) => {
            var docId = doc._id.toString();
            var _parentId = doc.parentId;
            doc.disable = true;
            // 保存更改
            doc.save((err, doc) => {
                if (err) {
                    cb(err.message, null);
                } else {
                    // 当删除的文件为文件夹时
                    if (doc.contentType == 'folder') {
                        this.module.update({ parentId: docId }, { parentId: _parentId }, { multi: true }, function (err, docs) {
                            if (err) {
                                cb(err.message, null);
                            } else {
                                cb(false, null);
                            };
                        });
                    } else {
                        cb(false, null);
                    };
                };
            });
        });
    };
};
DataBase.prototype.search = function (name, type, cb) {
    if (this.DBMessage.message) {
        cb(this.DBMessage.message, null);
    } else {
        var query = {}
        if (type != 'ALL') {
            query.contentType = type;
        } else {
            query.contentType = { $ne: 'folder' };
        };
        name = name.replace(/\*/g, '\\*');
        name = name.replace(/\//g, '\\/');
        name = name.replace(/\?/g, '\\?');
        name = name.replace(/\&/g, '\\&');
        name = name.replace(/\%/g, '\\%');
        name = name.replace(/\=/g, '\\=');
        name = name.replace(/\+/g, '\\+');

        query.$or = [
            { requestURL: { $regex: new RegExp(name) } },
            { title: { $regex: new RegExp(name) } }
        ]

        query.disable = false;
        if (this.DBMessage.message) {
            cb(this.DBMessage.message, null);
        } else {
            if (name.toString().length > 30) {
                cb('too lang', null);
            } else {
                this.module.find(query, function (err, docs) {
                    if (err) {
                        cb(err.message, null);
                    } else {
                        cb(false, formatDocs(docs));
                    };
                });
            };
        };
    }
};
DataBase.prototype.GetByArray = function (_array, cb) {
    if (this.DBMessage.message) {
        cb(this.DBMessage.message, null);
    } else {
        if (_array.length == 0) {
            cb(false, []);
            return;
        };
        var _data = [];
        var _this = this;
        var index = 0
        var findById = function () {
            _this.module.findById(_array[index], function (err, doc) {
                if (err) {
                    cb(err);
                } else {
                    _data.push(doc);
                    if (index >= _array.length - 1) {
                        cb(false, formatDocs(_data));
                    } else {
                        findById(index++);
                    };
                }
            });
        };
        findById();
    }
};

module.exports = function (options) {
    return new DataBase(options);
};